home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / MacTCP Switcher 1.0 / mswitch.c next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  12.6 KB  |  519 lines  |  [TEXT/KAHL]

  1. /*---------------------------------------------------------------------------
  2.  
  3.     MacTCP Switcher - A Program to Save and Restore MacTCP Settings
  4.     
  5.     John Norstad
  6.     Academic Computing and Network Services
  7.     Northwestern University
  8.     
  9.     j-norstad@nwu.edu
  10.     
  11.     Copyright © 1993, Northwestern University
  12.     
  13. ---------------------------------------------------------------------------*/
  14.  
  15. #include <AppleEvents.h>
  16. #include <GestaltEqu.h>
  17. #include <Traps.h>
  18. #include <Folders.h>
  19. #include <Aliases.h>
  20. #include <Script.h>
  21. #include <Palettes.h>
  22. #include <AppleTalk.h>
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28.  
  29. pascal OSErr SetDialogDefaultItem (DialogPtr theDialog,
  30.     short newItem) = {0x303C,0x0304,0xAA68};
  31.  
  32. pascal OSErr SetDialogCancelItem (DialogPtr theDialog,
  33.     short newItem) = {0x303C,0x0305,0xAA68};
  34.  
  35. pascal OSErr SetDialogTrackCursor (DialogPtr theDialog,
  36.     Boolean tracks) = {0x303C,0x0306,0xAA68};
  37.     
  38. pascal OSErr GetStdFilterProc (ProcPtr *theProc) =
  39.     {0x303C,0x0203,0xAA68};
  40.  
  41. #define kCreator     'MCPS'
  42. #define kFileType     'MCPT'
  43.  
  44. #define kMacTCPPrepCreator        'mtcp'
  45. #define kMacTCPPrepFileType        'mtpp'
  46.  
  47. #define kMacTCPConfigRsrcType    'ipln'
  48. #define kMacTCPConfigRsrcID        128
  49. #define kMacTCPDnrInfoRsrcType    'dnsl'
  50. #define kMacTCPDnrInfoRsrcID    128
  51.  
  52. #define kMacTCPDriverName         "\p.ipp"
  53.  
  54. #define kStringsID         128
  55. #define kMBarID         128
  56.  
  57. #define kErrAlert             128
  58. #define kUnexpectedErrAlert 129
  59. #define kSetMacTCPAlert        130
  60. #define kRestartAlert        132
  61. #define kMacTCPSetAlert        133
  62.  
  63. #define kNeedSystem7Alert    200
  64.  
  65. #define kSetMacTCPAlertSet        1
  66. #define kSetMacTCPAlertCancel    2
  67. #define kSetMacTCPAlertSave        3
  68.  
  69. #define kRestartAlertOK            1
  70. #define kRestartAlertRestart    2
  71.  
  72. #define kMacTCPPrepStr            1
  73. #define kSaveAsPromptStr        2
  74. #define kMacTCPStr                3
  75. #define kMacTCPNotFoundStr        4
  76. #define kCanOnlyOpenOneDocStr    5
  77.  
  78. #define kAppleMenu         128
  79. #define kEmptyItem        1
  80.  
  81. #define kFileMenu         129
  82.  
  83. #define kEditMenu         130
  84. #define kUndoItem         1
  85. #define kCutItem         3
  86. #define kCopyItem         4
  87. #define kPasteItem         5
  88. #define kClearItem         6
  89.  
  90. typedef struct TDialogCommandKeyItem {
  91.     short itemNumber;
  92.     char key;
  93. } TDialogCommandKeyItem;
  94.  
  95. static short gNumDialogCommandKeyItems;
  96. static TDialogCommandKeyItem gDialogCommandKeyItems[2];
  97.  
  98. static unsigned short NumToolboxTraps (void)
  99. {
  100.     return NGetTrapAddress(_InitGraf, ToolTrap) == 
  101.         NGetTrapAddress(0xAA6E, ToolTrap) ? 0x200 : 0x400;
  102. }
  103.  
  104. static TrapType GetTrapType (unsigned short theTrap)
  105. {
  106.     return (theTrap & 0x0800) > 0 ? ToolTrap : OSTrap;
  107. }
  108.  
  109. static Boolean TrapAvailable (unsigned short theTrap)
  110. {
  111.     TrapType tType;
  112.     
  113.     tType = GetTrapType(theTrap);
  114.     if (tType == ToolTrap) {
  115.         theTrap = theTrap & 0x07ff;
  116.         if (theTrap >= NumToolboxTraps()) theTrap = _Unimplemented;
  117.     }
  118.     return NGetTrapAddress(theTrap, tType) != 
  119.         NGetTrapAddress(_Unimplemented, ToolTrap);
  120. }
  121.  
  122. static void DlgFlashButton (DialogPtr dlg, short item)
  123. {
  124.     short itemType;
  125.     ControlHandle theItem;
  126.     Rect box;
  127.     long myticks;
  128.     
  129.     GetDItem(dlg, item, &itemType, (Handle*)&theItem, &box);
  130.     HiliteControl(theItem, 1);
  131.     Delay(8, &myticks);
  132.     HiliteControl(theItem, 0);
  133. }
  134.  
  135. static pascal Boolean DialogFilter (DialogPtr dlg, EventRecord *theEvent, 
  136.     short *itemHit)
  137. {
  138.     GrafPtr savedPort;
  139.     Boolean result = false;
  140.     OSErr err;
  141.     ProcPtr standardFilterProc;
  142.     char key;
  143.     TDialogCommandKeyItem *p, *pEnd;
  144.  
  145.     if ((theEvent->what == keyDown || theEvent->what == autoKey) &&
  146.         (theEvent->modifiers & cmdKey) != 0)
  147.     {
  148.         key = toupper(theEvent->message & charCodeMask);
  149.         p = gDialogCommandKeyItems;
  150.         pEnd = p + gNumDialogCommandKeyItems;
  151.         while (p < pEnd) {
  152.             if (key == toupper(p->key)) {
  153.                 *itemHit = p->itemNumber;
  154.                 DlgFlashButton(dlg, p->itemNumber);
  155.                 return true;
  156.             }
  157.             p++;
  158.         }
  159.     }
  160.     GetPort(&savedPort);
  161.     SetPort(dlg);
  162.     err = GetStdFilterProc(&standardFilterProc);
  163.     if (err == noErr) {
  164.         result = ((ModalFilterProcPtr)standardFilterProc)(dlg, theEvent, itemHit);
  165.     }
  166.     SetPort(savedPort);
  167.     return result;
  168. }
  169.  
  170. static void MyModalDialog (short dlgID, short okItem, short cancelItem, 
  171.     StringPtr p1, StringPtr p2, short numCommandKeys, short *itemHit)
  172. {
  173.     DialogPtr dlg;
  174.     short hit;
  175.     
  176.     InitCursor();
  177.     dlg = GetNewDialog(dlgID, nil, (WindowPtr)-1);
  178.     if (okItem != 0) SetDialogDefaultItem(dlg, okItem);
  179.     if (cancelItem != 0) SetDialogCancelItem(dlg, cancelItem);
  180.     ParamText(p1, p2, "\p", "\p");
  181.     gNumDialogCommandKeyItems = numCommandKeys;
  182.     ModalDialog(DialogFilter, &hit);
  183.     DisposeDialog(dlg);
  184.     if (itemHit != nil) *itemHit = hit;
  185. }
  186.  
  187. static OSErr MyFSpOpenResFile (FSSpec *fSpec, short permission, short *refNum)
  188. {
  189.     OSErr err;
  190.     
  191.     *refNum = FSpOpenResFile(fSpec, permission);
  192.     if (*refNum != -1) return noErr;
  193.     err = ResError();
  194.     if (err != noErr) return err;
  195.     return resFNotFound;
  196. }
  197.  
  198. static OSErr MyFSpCreateResFile (FSSpec *fSpec, OSType creator, OSType fileType,
  199.     ScriptCode scriptTag)
  200. {
  201.     FSpCreateResFile(fSpec, creator, fileType, scriptTag);
  202.     return ResError();
  203. }
  204.  
  205. static OSErr MyGet1Resource (OSType type, short id, Handle *h)
  206. {
  207.     OSErr err;
  208.     
  209.     *h = Get1Resource(type, id);
  210.     if (*h != nil) return noErr;
  211.     err = ResError();
  212.     if (err != noErr) return err;
  213.     return resNotFound;
  214. }
  215.  
  216. static OSErr MyAddResource (Handle h, OSType type, short id)
  217. {
  218.     Handle rsrc;
  219.     OSErr err;
  220.     
  221.     rsrc = Get1Resource(type, id);
  222.     if (rsrc != nil) {
  223.         RmveResource(rsrc);
  224.         err = ResError();
  225.         if (err != noErr) return err;
  226.         DisposeHandle(rsrc);
  227.     }
  228.     AddResource(h, type, id, "\p");
  229.     return ResError();
  230. }
  231.  
  232. static void ErrorMessage (short errNum)
  233. {
  234.     Str255 msg;
  235.  
  236.     GetIndString(msg, kStringsID, errNum);
  237.     MyModalDialog(kErrAlert, ok, 0, msg, "\p", 0, nil);
  238. }
  239.  
  240. static void UnexpectedErrorMessage (OSErr err)
  241. {
  242.     Str255 errStr;
  243.     
  244.     NumToString(err, errStr);
  245.     MyModalDialog(kUnexpectedErrAlert, ok, 0, errStr, "\p", 0, nil);
  246. }
  247.  
  248. static Boolean MacTCPIsOpen (void)
  249. {
  250.     DCtlHandle *unitTableEntryPtr, *unitTableEnd, dctlHandle;
  251.     short flags;
  252.     Ptr driver;
  253.  
  254.     unitTableEnd = UTableBase + UnitNtryCnt;
  255.     for (unitTableEntryPtr = UTableBase; 
  256.         unitTableEntryPtr < unitTableEnd; 
  257.         unitTableEntryPtr++) 
  258.     {
  259.         dctlHandle = *unitTableEntryPtr;
  260.         if (dctlHandle != nil) {
  261.             flags = (**dctlHandle).dCtlFlags;
  262.             driver = (**dctlHandle).dCtlDriver;
  263.             if (flags & 0x40) driver = *(Handle)driver;
  264.             if (EqualString(kMacTCPDriverName, (StringPtr)(driver+18), true, true))
  265.                 return (flags & 0x20) != 0;
  266.         }
  267.     }
  268.     return false;
  269. }
  270.  
  271. static void Restart (void)
  272. {
  273.     ProcessSerialNumber psn;
  274.     AppleEvent message;
  275.     AEAddressDesc targetAddr;
  276.     OSErr err;
  277.     Boolean targetAddrCreated = false;
  278.     Boolean messageCreated = false;
  279.     
  280.     psn.highLongOfPSN = 0;
  281.     psn.lowLongOfPSN = kSystemProcess;
  282.     err = AECreateDesc(typeProcessSerialNumber, (Ptr)&psn, 
  283.         sizeof(ProcessSerialNumber), &targetAddr);
  284.     if (err != noErr) goto exit;
  285.     targetAddrCreated = true;
  286.     err = AECreateAppleEvent(kCoreEventClass, kAERestart,
  287.         &targetAddr, kAutoGenerateReturnID, kAnyTransactionID, &message);
  288.     if (err != noErr) goto exit;
  289.     messageCreated = true;
  290.     err = AESend(&message, nil, kAENoReply | kAECanInteract, kAENormalPriority,
  291.         kAEDefaultTimeout, nil, nil);
  292.     if (err != noErr) goto exit;
  293.     AEDisposeDesc(&message);
  294.     AEDisposeDesc(&targetAddr);
  295.     return;
  296.     
  297. exit:
  298.  
  299.     if (messageCreated) AEDisposeDesc(&message);
  300.     if (targetAddrCreated) AEDisposeDesc(&targetAddr);
  301.     UnexpectedErrorMessage(err);
  302. }
  303.  
  304. static OSErr CopyResources (FSSpec *source, FSSpec *dest, OSType creator, OSType fileType)
  305. {
  306.     short refNum = -1;
  307.     OSErr err;
  308.     Handle ipConfig, dnrInfo;
  309.     
  310.     err = MyFSpOpenResFile(source, fsRdPerm, &refNum);
  311.     if (err != noErr) goto exit;
  312.     err = MyGet1Resource(kMacTCPConfigRsrcType, kMacTCPConfigRsrcID, &ipConfig);
  313.     if (err != noErr) goto exit;
  314.     DetachResource(ipConfig);
  315.     err = MyGet1Resource(kMacTCPDnrInfoRsrcType, kMacTCPDnrInfoRsrcID, &dnrInfo);
  316.     if (err != noErr) goto exit;
  317.     DetachResource(dnrInfo);
  318.     CloseResFile(refNum);
  319.     refNum = -1;
  320.     
  321.     err = MyFSpOpenResFile(dest, fsRdWrPerm, &refNum);
  322.     if (err == fnfErr) {
  323.         err = MyFSpCreateResFile(dest, creator, fileType, smSystemScript);
  324.         if (err != noErr) goto exit;
  325.         err = MyFSpOpenResFile(dest, fsRdWrPerm, &refNum);
  326.     }
  327.     if (err != noErr) goto exit;
  328.     err = MyAddResource(ipConfig, kMacTCPConfigRsrcType, kMacTCPConfigRsrcID);
  329.     if (err != noErr) goto exit;
  330.     err = MyAddResource(dnrInfo, kMacTCPDnrInfoRsrcType, kMacTCPDnrInfoRsrcID);
  331.     if (err != noErr) goto exit;
  332.     CloseResFile(refNum);
  333.     return noErr; 
  334.     
  335. exit:
  336.  
  337.     if (refNum != -1) CloseResFile(refNum);
  338.     return err;
  339. }
  340.  
  341. static OSErr SaveMacTCPConfigToFile (void)
  342. {
  343.     Str255 prompt;
  344.     StandardFileReply sfReply;
  345.     FSSpec fSpec;
  346.     FInfo fndrInfo;
  347.     OSErr err;
  348.  
  349.     GetIndString(prompt, kStringsID, kSaveAsPromptStr);
  350.     StandardPutFile(prompt, "\p", &sfReply);
  351.     if (!sfReply.sfGood) return userCanceledErr;
  352.     err = FindFolder(kOnSystemDisk, kPreferencesFolderType, true, 
  353.         &fSpec.vRefNum, &fSpec.parID);
  354.     if (err != noErr) return err;
  355.     GetIndString(fSpec.name, kStringsID, kMacTCPPrepStr);
  356.     err = FSpGetFInfo(&fSpec, &fndrInfo);
  357.     if (err == fnfErr) {
  358.         err = FindFolder(kOnSystemDisk, kControlPanelFolderType, true,
  359.             &fSpec.vRefNum, &fSpec.parID);
  360.         if (err != noErr) return err;
  361.         GetIndString(fSpec.name, kStringsID, kMacTCPStr);
  362.         err = FSpGetFInfo(&fSpec, &fndrInfo);
  363.     }
  364.     if (err != noErr) return err;
  365.     return CopyResources(&fSpec, &sfReply.sfFile, kCreator, kFileType);
  366. }
  367.  
  368. static pascal OSErr HandleAEOpenApp (AppleEvent *event, AppleEvent *reply, long refCon)
  369. {
  370.     OSErr err;
  371.  
  372.     err = SaveMacTCPConfigToFile();
  373.     if (err == userCanceledErr) return noErr;
  374.     if (err != noErr) goto exit;
  375.     return noErr;
  376.     
  377. exit:
  378.  
  379.     if (err == fnfErr) {
  380.         ErrorMessage(kMacTCPNotFoundStr);
  381.     } else {
  382.         UnexpectedErrorMessage(err);
  383.     }
  384.     return err;
  385. }
  386.  
  387. static pascal OSErr HandleAEOpenDoc (AppleEvent *event, AppleEvent *reply, long refCon)
  388. {
  389.     OSErr err;
  390.     AEDescList docList;
  391.     long numItems;
  392.     AEKeyword keywd;
  393.     DescType returnedType;
  394.     Size actualSize;
  395.     FSSpec source, dest;
  396.     short itemHit;
  397.     
  398.     err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docList);
  399.     if (err != noErr) goto exit;
  400.     err = AECountItems(&docList, &numItems);
  401.     if (err != noErr) goto exit;
  402.     if (numItems != 1) {
  403.         ErrorMessage(kCanOnlyOpenOneDocStr);
  404.         return noErr;
  405.     }
  406.     err = AEGetNthPtr(&docList, 1, typeFSS, &keywd, &returnedType,
  407.         (Ptr)&source, sizeof(source), &actualSize);
  408.     if (err != noErr) goto exit;
  409.     err = AEDisposeDesc(&docList);
  410.     if (err != noErr) goto exit;
  411.     while (true) {
  412.         gDialogCommandKeyItems[0].itemNumber = kSetMacTCPAlertSave;
  413.         gDialogCommandKeyItems[0].key = 'S';
  414.         MyModalDialog(kSetMacTCPAlert, kSetMacTCPAlertSet, kSetMacTCPAlertCancel,
  415.             source.name, "\p", 1, &itemHit);
  416.         if (itemHit == kSetMacTCPAlertSet) break;
  417.         if (itemHit == kSetMacTCPAlertCancel) return noErr;
  418.         if (itemHit == kSetMacTCPAlertSave) {
  419.             err = SaveMacTCPConfigToFile();
  420.             if (err == userCanceledErr) return noErr;
  421.             if (err != noErr) goto exit;
  422.         }
  423.     }
  424.     err = FindFolder(kOnSystemDisk, kPreferencesFolderType, true, 
  425.         &dest.vRefNum, &dest.parID);
  426.     if (err != noErr) goto exit;
  427.     GetIndString(dest.name, kStringsID, kMacTCPPrepStr);
  428.     err = CopyResources(&source, &dest, kMacTCPPrepCreator, kMacTCPPrepFileType);
  429.     if (err != noErr) goto exit;
  430.     if (MacTCPIsOpen()) {
  431.         gDialogCommandKeyItems[0].itemNumber = kRestartAlertRestart;
  432.         gDialogCommandKeyItems[0].key = 'R';
  433.         MyModalDialog(kRestartAlert, ok, 0, "\p", "\p", 1, &itemHit);
  434.         if (itemHit == kRestartAlertRestart) Restart();
  435.     } else {
  436.         MyModalDialog(kMacTCPSetAlert, ok, 0, "\p", "\p", 0, nil);
  437.     }
  438.     return noErr;
  439.  
  440. exit:
  441.  
  442.     UnexpectedErrorMessage(err);
  443.     return err;
  444. }
  445.  
  446. static pascal OSErr HandleAEPrintDoc (AppleEvent *event, AppleEvent *reply, long refCon)
  447. {
  448.     return noErr;
  449. }
  450.  
  451. static pascal OSErr HandleAEQuit (AppleEvent *event, AppleEvent *reply, long refCon)
  452. {
  453.     return noErr;
  454. }
  455.  
  456. static void Init (void)
  457. {
  458.     EventRecord ev;
  459.     long systemVersion;
  460.     OSErr err;
  461.     Boolean haveSystem7;
  462.  
  463.     MaxApplZone();
  464.     
  465.     InitGraf(&qd.thePort);
  466.     InitFonts();
  467.     InitWindows();
  468.     InitMenus();
  469.     TEInit();
  470.     InitDialogs(nil);
  471.     InitCursor();
  472.  
  473.     FlushEvents(everyEvent,0);
  474.     EventAvail(everyEvent, &ev);
  475.  
  476.     haveSystem7 = TrapAvailable(_Gestalt);
  477.     if (haveSystem7) {
  478.         err = Gestalt(gestaltSystemVersion, &systemVersion);
  479.         haveSystem7 = err == noErr && systemVersion >= 0x0700;
  480.     }
  481.     if (!haveSystem7) {
  482.         StopAlert(kNeedSystem7Alert, nil);
  483.         ExitToShell();
  484.     }
  485.  
  486.     SetMenuBar(GetNewMBar(kMBarID));
  487.     AddResMenu(GetMHandle(kAppleMenu), 'DRVR');
  488.     DrawMenuBar();
  489.  
  490.     AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  491.         HandleAEOpenApp, 0, false);
  492.     AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  493.         HandleAEOpenDoc, 0, false);
  494.     AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  495.         HandleAEPrintDoc, 0, false);
  496.     AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  497.         HandleAEQuit, 0, false);
  498. }
  499.  
  500. static void MainEvent (void)
  501. {
  502.     EventRecord ev;
  503.     Boolean    gotEvt;
  504.  
  505.     while (true) {
  506.         gotEvt = WaitNextEvent(everyEvent, &ev, 10, nil);
  507.         if (gotEvt && ev.what == kHighLevelEvent) {
  508.             AEProcessAppleEvent(&ev);
  509.             break;
  510.         }
  511.     }
  512. }
  513.  
  514. void main (void)
  515. {
  516.     Init();
  517.     MainEvent();
  518. }
  519.